package org.univie.mappr;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Vector;

import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

import android.util.Log;

/**
 * Stores the information of photos locally, so that they can be retrieved later
 */
public abstract class PhotoCache {

	private static final String TAG = "org.univie.mappr.PhotoCache";

	private static final int MAX_CACHED = 200;
	// private static final String CACHE_NAME =
	// "Android/data/org.univie.mappr/files/photocache/";
	private static final String CACHE_NAME = "MapprPhotoInfo";
	private static File CACHE_DIR;
	private static File SDCARD;

	/**
	 * Adds the XML response for a photo to the cache Started in new Thread
	 * 
	 * @param id
	 *            The id of the photo
	 * @param xml
	 *            is the XMLDocument which should be saved
	 */
	public static void addXmlForPhoto(final String id, final Document xml) {

		Thread saveXml = new Thread() {

			public void run() {
				XMLOutputter output = new XMLOutputter();

				try {
					File outputFile = new File(CACHE_DIR, id + ".xml");
					FileOutputStream outStream = new FileOutputStream(
							outputFile);
					output.output(xml, outStream);
					
					// If the maximum size of the cache was exceeded, delete the first file
					File file_to_delete = CACHE_DIR.listFiles()[0];
					if (CACHE_DIR.listFiles().length > MAX_CACHED) {
						for(File tmp_file : CACHE_DIR.listFiles()){
							// find the oldest file and delete it
							if(file_to_delete.lastModified() > tmp_file.lastModified()){
								tmp_file = file_to_delete;
							}
						}
						file_to_delete.delete();
					}
					
				} catch (FileNotFoundException e1) {
					Log.e(TAG, "File not found Exception: \n" + e1.toString());
					e1.printStackTrace();
				} catch (IOException e) {
					Log.e(TAG, "IOException \n" + e.toString());
					e.printStackTrace();
				} catch (Exception e) {
					Log.e(TAG, "General error while writing to the cache");
				}
			}
		};
		saveXml.start();
	}

	/**
	 * Checks whether there already is an entry for a photo
	 * 
	 * @param id
	 *            The id of the photo
	 * @return Whether ther is an entry for the photo
	 */
	public static boolean hasEntryForId(String id) {
		File file = new File(CACHE_DIR, id + ".xml");
		return (file.exists() && file.canRead());
	}

	/**
	 * Returns the raw XML string for a photo, to be parsed in the FlickrClient.
	 * 
	 * @param id
	 *            The id of the photo
	 * @return The raw XML string for the photo
	 */
	public static String getXmlForPhoto(String id) {
		XMLOutputter output = new XMLOutputter();
		SAXBuilder builder = new SAXBuilder();
		Document doc = null;
		if (hasEntryForId(id)) {
			File inputFile = new File(CACHE_DIR, id + ".xml");
			FileInputStream fis;
			Log.d(TAG, "Trying to get the file");
			try {
				fis = new FileInputStream(inputFile);
				doc = builder.build(fis);
				Log.d(TAG, "returning the output");
				return output.outputString(doc);
			} catch (JDOMException e) {
				Log.e(TAG, "JDOMException: " + e.toString());
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				Log.e(TAG, "IOMException: " + e.toString());
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return null;
	}

	public static void cleanup() {
		Log.d(TAG, "Deleting files - number of files: "+CACHE_DIR.list().length);
		try {
			for (File to_delete : CACHE_DIR.listFiles()) {
			//	File to_delete = new File(CACHE_DIR, filename + ".jpg");
				to_delete.delete();		
			}
		} catch (Exception e) {
			Log.e(TAG, "Error while cleaning up the cache. Some files might still be left over.");
		}
	}

	/**
	 * 
	 * @return the size of the CacheDir in byte
	 * 
	 */
	public static long get_size(){
		long slh = 0;
		for(File tmp_file : CACHE_DIR.listFiles()){
			slh += tmp_file.length();
		}
		return slh;
	}
	
	
	/**
	 * Initializes the folders of the cache on the SD card
	 * 
	 * @param sdCard
	 * @throws IOException
	 */
	public static void initialize(File sdCard) throws IOException {
		SDCARD = sdCard;
		CACHE_DIR = new File(SDCARD, CACHE_NAME);
		CACHE_DIR.mkdirs();
	}
}
